<?php
/**
 * Created by PhpStorm.
 * User: 李大爷
 * Date: 2019/3/8
 * Time: 9:57
 */

namespace app\controllers;

use app\models\User;
use Yii;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use app\models\Voice;
use yii\web\NotFoundHttpException;

class VoiceController extends BaseController
{

    public function actionIndex()
    {
        if (Yii::$app->request->isAjax){
            //筛选
            $where = ['and'];
            $phone = Yii::$app->request->get('phone');
            if ($phone){
                $where[] = ['like','phone',$phone];
            }
            $user_id = Yii::$app->request->get('user_id');
            if ($user_id){
                $where[] = ['=','user_id',$user_id];
            }
            $created_at_start = Yii::$app->request->get('created_at_start');
            $created_at_end = Yii::$app->request->get('created_at_end');
            if ($created_at_start && !$created_at_end){
                $where[] = ['>=','created_at',strtotime($created_at_start)];
            }elseif (!$created_at_start && $created_at_end){
                $where[] = ['<=','created_at',strtotime($created_at_end)];
            }elseif ($created_at_start && $created_at_end){
                $where[] = ['between','created_at',strtotime($created_at_start),strtotime($created_at_end)];
            }

            $query = Voice::find()->with('user')->where($where)->orderBy('id desc');
            $count = $query->count();

            $page = Yii::$app->request->get('page',1);
            $limit = Yii::$app->request->get('limit',10);
            $data = $query->offset(($page-1)*$limit)->limit($limit)->asArray()->all();
            foreach ($data as &$d){
                $d['user_name'] = $d['user']['username'];
                $d['per'] = ArrayHelper::getValue((new Voice())->per_arr,$d['per']);
                $d['destroy_url'] = Url::to(['destroy']);
                $d['play_url'] = Url::to(['play','id'=>$d['id']]);
                $d['download_url'] = Url::to(['download','id'=>$d['id']]);
                $d['created_at'] = date('Y-m-d H:i',$d['created_at']);
            }
            return $this->asJson([
                'code' => 0,
                'msg' => '请求成功',
                'count' => $count,
                'data' => $data
            ]);
        }
        $users = User::find()->all();
        return $this->render('index',['users'=>$users]);
    }

    /**
     * 发送语音信息
     * @return string|\yii\web\Response
     */
    public function actionCreate()
    {
        $model = new Voice();
        $trunks = (new Query())->from('trunks')->all($this->asterisk_db);
        if (Yii::$app->request->isPost){
            $data = Yii::$app->request->post();
            if ($model->load($data,'')&&$model->send()){
                Yii::$app->session->setFlash('info','发送成功');
                return $this->redirect(['index']);
            }
        }
        return $this->render('create',['model'=>$model,'trunks'=>$trunks]);
    }

    /**
     * 删除
     * @return \yii\web\Response
     */
    public function actionDestroy()
    {
        $ids = Yii::$app->request->post('ids');
        if (!is_array($ids)||empty($ids)){
            return $this->asJson(['code'=>1,'msg'=>'请选择删除项']);
        }
        $transaction = Voice::getDb()->beginTransaction();
        try{
            $voices = Voice::findAll(['id'=>$ids]);
            foreach ($voices as $voice){
                unlink($voice->file);
                $voice->delete();
            }
            $transaction->commit();
            return $this->asJson(['code'=>0,'msg'=>'删除成功']);
        }catch (\Exception $exception){
            $transaction->rollBack();
            return $this->asJson(['code'=>1,'msg'=>'删除失败','data'=>$exception->getMessage()]);
        }
    }

    /**
     * 播放
     * @param $id
     * @throws NotFoundHttpException
     */
    public function actionPlay($id)
    {
        $voice = Voice::findOne($id);
        if ($voice==false){
            throw new NotFoundHttpException('记录不存在');
        }
        if ($voice['file'] && is_file($voice['file'])){
            $path = $voice['file'];
            $fileSize = filesize($path);
            $etag = md5(filemtime($path));
            $fp = fopen($path, 'rb');
            if (!$fp) {
                die('Could not open file');
            }
            $start = 0;
            $end = $fileSize - 1;
            if (isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
                //获取请求头中的Range字段
                $range = explode('-', substr($_SERVER['HTTP_RANGE'], strlen('bytes=')));

                $start = $range[0];
                if ($range[1] > 0) {
                    $end = $range[1];
                }

                //构造断点续传响应头
                header('HTTP/1.1 206 Partial Content');
                header('Status: 206');
                header('Accept-Ranges: bytes');
                header('Content-Range: bytes ' . $start . '-' . $end . '/' . $fileSize);
                header('Content-Length: ' . ($end - $start + 1));
            } else {
                header('Content-Length: ' . $fileSize);
            }
            header('Content-Type: audio/mpeg');
            header('Last-Modified: ' . date('D, d M Y H:i:s \G\M\T', filemtime($path)));
            header('ETag: "' . $etag . '"');
            header('Expires: 0');
            if ($start > 0) {
                fseek($fp, $start); //移动文件指针
            }
            $bytesPosition = $start;
            while (!feof($fp) && $bytesPosition <= $end) {
                $chunk = 1024 * 1024 * 50; //每次读取50k
                if ($bytesPosition + $chunk > $end + 1) {
                    $chunk = $end - $bytesPosition + 1;
                }
                $chunk = fread($fp, $chunk);
                if (!$chunk) {
                    throw new NotFoundHttpException('无法读取文件');
                }
                print($chunk);
                flush();
                $bytesPosition += $chunk;
            }
            fclose($fp);
        }
        throw new NotFoundHttpException('文件不存在');
    }

    /**
     * 下载
     * @param $id
     * @return bool|string
     * @throws NotFoundHttpException
     */
    public function actionDownload($id)
    {
        $voice = Voice::findOne($id);
        if ($voice==false){
            throw new NotFoundHttpException('记录不存在');
        }
        if ($voice['file'] && is_file($voice['file'])){
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Content-Disposition: attachment; filename = " . $voice['file']);
            header("Content-Length: " . filesize($voice['file']));
            header("Content-Type: application/octet-stream");
            return file_get_contents($voice['file']);
        }
        throw new NotFoundHttpException('文件不存在');
    }
    
}